package proxy

import (
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"
	"time"
)

// handleConnectRequest 处理CONNECT请求（HTTPS隧道）
func (s *Server) handleConnectRequest(w http.ResponseWriter, r *http.Request) {
	// 解析目标地址
	host, port, err := net.SplitHostPort(r.Host)
	if err != nil {
		// 如果没有端口，默认使用443
		host = r.Host
		port = "443"
	}

	fmt.Printf("🔗 CONNECT请求: %s:%s\n", host, port)

	// 由于HTTP服务器路径已废弃，统一使用TCP路径处理
	// 获取客户端连接
	hijacker, ok := w.(http.Hijacker)
	if !ok {
		http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
		return
	}

	clientConn, _, err := hijacker.Hijack()
	if err != nil {
		fmt.Printf("❌ Hijack连接失败: %v\n", err)
		return
	}

	// 统一使用TCP路径处理
	s.handleConnectRequestTCP(clientConn, r)
}

// handleTransparentConnectRequest 处理透明的CONNECT请求
func (s *Server) handleTransparentConnectRequest(w http.ResponseWriter, r *http.Request, host, port string) {
	fmt.Printf("🔄 透明模式处理CONNECT: %s:%s\n", host, port)

	// 建立到目标服务器的连接
	targetConn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), 10*time.Second)
	if err != nil {
		http.Error(w, "Failed to connect to target", http.StatusBadGateway)
		fmt.Printf("❌ 连接目标服务器失败: %v\n", err)
		return
	}
	defer targetConn.Close()

	// 获取客户端连接
	hijacker, ok := w.(http.Hijacker)
	if !ok {
		http.Error(w, "Hijacking not supported", http.StatusInternalServerError)
		return
	}

	clientConn, _, err := hijacker.Hijack()
	if err != nil {
		fmt.Printf("❌ Hijack连接失败: %v\n", err)
		return
	}
	defer clientConn.Close()

	// 发送200 Connection Established响应（包含必要的HTTP头）
	response := "HTTP/1.1 200 Connection Established\r\n" +
		"Connection: close\r\n" +
		"\r\n"
	if _, err := clientConn.Write([]byte(response)); err != nil {
		fmt.Printf("❌ 发送CONNECT响应失败: %v\n", err)
		return
	}

	fmt.Printf("✅ 透明隧道建立成功: %s:%s\n", host, port)

	// 双向数据转发
	go func() {
		defer clientConn.Close()
		defer targetConn.Close()
		io.Copy(targetConn, clientConn)
	}()

	io.Copy(clientConn, targetConn)
}

// handleConnectRequestTCP 处理TCP连接的CONNECT请求
func (s *Server) handleConnectRequestTCP(clientConn net.Conn, req *http.Request) {
	// 解析目标地址
	host := req.URL.Host
	if host == "" {
		host = req.Host
	}

	// 如果没有端口，添加默认端口
	if !strings.Contains(host, ":") {
		host += ":443"
	}

	fmt.Printf("🔗 处理CONNECT请求: %s\n", host)

	// 发送200 Connection Established响应（包含必要的HTTP头）
	response := "HTTP/1.1 200 Connection Established\r\n" +
		"Connection: close\r\n" +
		"\r\n"
	if _, err := clientConn.Write([]byte(response)); err != nil {
		fmt.Printf("❌ 发送CONNECT响应失败: %v\n", err)
		return
	}

	fmt.Printf("✅ CONNECT响应已发送: %s\n", host)

	// 判断是否启用HTTPS拦截
	if s.config != nil && s.config.InterceptHTTPS {
		fmt.Printf("🔒 启用HTTPS拦截模式: %s\n", host)
		s.handleMITMConnectRequestTCP(clientConn, host)
	} else {
		fmt.Printf("🔄 启用透明转发模式: %s\n", host)
		s.handleTransparentConnectRequestTCP(clientConn, host)
	}
}

// handleMITMConnectRequestTCP 处理MITM拦截的CONNECT请求
func (s *Server) handleMITMConnectRequestTCP(clientConn net.Conn, host string) {
	// 获取主机名（去掉端口）
	hostname := strings.Split(host, ":")[0]

	// 生成或获取证书
	cert, err := s.certManager.GetCertificateForHost(hostname)
	if err != nil {
		fmt.Printf("❌ 获取证书失败: %v\n", err)
		// 如果证书获取失败，回退到透明转发
		s.handleTransparentConnectRequestTCP(clientConn, host)
		return
	}

	fmt.Printf("🔐 证书已准备: %s\n", hostname)

	// 执行MITM拦截
	s.performMITMInterceptionTCP(clientConn, host, cert)
}

// handleTransparentConnectRequestTCP 处理透明转发的CONNECT请求
func (s *Server) handleTransparentConnectRequestTCP(clientConn net.Conn, host string) {
	// 连接到目标服务器
	targetConn, err := net.DialTimeout("tcp", host, 10*time.Second)
	if err != nil {
		fmt.Printf("❌ 连接目标服务器失败: %v\n", err)
		return
	}
	defer targetConn.Close()

	fmt.Printf("✅ 透明隧道建立成功: %s\n", host)

	// 双向数据转发
	go func() {
		defer clientConn.Close()
		defer targetConn.Close()
		io.Copy(targetConn, clientConn)
	}()

	io.Copy(clientConn, targetConn)
}
